package com.leyou.trade.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.auth.utils.UserContext;
import com.leyou.common.exception.LyException;
import com.leyou.item.client.ItemClient;
import com.leyou.item.dto.SkuDTO;
import com.leyou.trade.dto.OrderDTO;
import com.leyou.trade.dto.OrderVO;
import com.leyou.trade.entity.Order;
import com.leyou.trade.entity.OrderDetail;
import com.leyou.trade.entity.OrderLogistics;
import com.leyou.trade.mapper.OrderMapper;
import com.leyou.trade.service.CartService;
import com.leyou.trade.service.OrderService;
import com.leyou.user.client.UserClient;
import com.leyou.user.dto.AddressDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    private OrderDetailServiceImpl detailService;

    private OrderLogisticsServiceImpl logisticsService;

    private ItemClient itemClient;

    private UserClient userClient;

    public OrderServiceImpl(
            OrderDetailServiceImpl detailService,
            OrderLogisticsServiceImpl logisticsService,
            ItemClient itemClient, UserClient userClient) {
        this.detailService = detailService;
        this.logisticsService = logisticsService;
        this.itemClient = itemClient;
        this.userClient = userClient;
    }

    //引入购物车,调用根据skuID删除购物车商品方法
    @Autowired
    private CartService cartService;

    /**
     * 下单
     * 1.处理订单
     * 2.处理订单详情
     * 3.处理收货信息
     * @param orderDTO
     */
    @Transactional
    @Override
    public Long createOrder(OrderDTO orderDTO) {

        //map的key为sku的id，value就是当前sku对应的被购买的数量
        Map<Long, Integer> carts = orderDTO.getCarts();
        if (CollectionUtils.isEmpty(carts) || orderDTO.getAddressId() == null || orderDTO.getPaymentType() == null) {
            throw new LyException(400,"用户输入信息有误");
        }

        //1.order
        //orderId会自动生成（mybatis-plus，使用idWorker）
        Order order = new Order();
        //1.1用户id
        Long userId = UserContext.getUser().getId();
        order.setUserId(userId);

        //1.2金额相关信息
        //1.2.1获取所有sku的id
        ArrayList<Long> idList = new ArrayList<>(carts.keySet());
        //1.2.2查询sku
        List<SkuDTO> skuDTOS = itemClient.listSkuByIds(idList);
        //1.2.3计算金额的和
        long total = 0;
        for (SkuDTO skuDTO : skuDTOS) {
            //总价  sum(单价*数量)
            int num = carts.get(skuDTO.getId());
            total += num*skuDTO.getPrice();
        }
        //1.2.4填写金额数据
        order.setTotalFee(total);
        order.setPaymentType(orderDTO.getPaymentType());
        //全场包邮
        order.setPostFee(0L);
        order.setActualFee(total+ order.getPostFee()/*-优惠金额*/);

        //1.3订单状态初始化
        order.setStatus(1);
        //1.4保存订单到数据库,并主键回显
        this.save(order);


        //2.orderdetail
        //2.1根据skuDTo的集合封装orderDetails
        List<OrderDetail> orderDetails = skuDTOS.stream().map(skuDTO -> {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(order.getOrderId());
            orderDetail.setSkuId(skuDTO.getId());
            //商品数量
            orderDetail.setNum(carts.get(skuDTO.getId()));
            orderDetail.setTitle(skuDTO.getTitle());
            orderDetail.setPrice(skuDTO.getPrice());
            orderDetail.setSpec(skuDTO.getSpecialSpec());
            orderDetail.setImage(StringUtils.substringBefore(skuDTO.getImages(),","));
            return orderDetail;
        }).collect(Collectors.toList());

        //2.2批量保存orderDetails
        this.detailService.saveBatch(orderDetails);


        //3.orderLogistics
        // 3.1根据用户id以及地址id查询对应的地址信息
        AddressDTO addressDTO = userClient.queryUserAddress(userId, orderDTO.getAddressId());
        OrderLogistics orderLogistics = new OrderLogistics();
        //转换
        BeanUtils.copyProperties(addressDTO,orderLogistics);
        //3.2填写物流信息
        orderLogistics.setOrderId(order.getOrderId());
        //3.3保存到数据库
        this.logisticsService.save(orderLogistics);

        //4.减库存,两个参数分别为skuId，以及要扣减的数量
        this.itemClient.minusStock(carts);


        //5.删除MongoDB中购物车对应的商品数据
        for (Map.Entry<Long, Integer> entry : carts.entrySet()) {
            Long skuId = entry.getKey();
            cartService.deleteCartItem(skuId);
        }


        //返回订单编号
        return order.getOrderId();


    }

    /**
     * 查询订单
     * @param orderId
     * @return
     */
    @Override
    public OrderVO queryOrderByOId(Long orderId) {
        Order order = this.getById(orderId);

        return new OrderVO(order) ;

    }

    /**
     * 查询订单支付状态
     * @param orderId
     * @return
     */
    @Override
    public Integer queryOrderState(Long orderId) {
        Order order = this.getById(orderId);
        if (order == null) {
            throw new LyException(400, "订单不存在！");
        }
        Integer status = order.getStatus();
        return status;
    }
}